using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Calendar = PHSRAG.WebControls.Calendar;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Policy;
using PHSRAG.Insight21.SearchContext;

namespace PHSRAG.Insight21.InsightWebControls
{
    public abstract class BaseSearch : WebControl
    {
        private const int defaultSelectedIndex = -1;
        /// <summary>
        /// Set the state of all child controls to reflect the search criteria (if any).
        /// </summary>
        /// <param name="searchCriteria">The search criteia (name/value pairs)</param>
        protected virtual void SetControlState(SearchCriteria searchCriteria)
        {
            if (searchCriteria != null)
            {
                foreach (string key in searchCriteria.Keys)
                {
                    Control c = FindControl(key);
                    if (c != null)
                    {
                        DropDownList ddl = c as DropDownList;
                        if (ddl != null)
                        {
                            ListItem item = ddl.Items.FindByValue(searchCriteria[key]);
                            if (item != null)
                                ddl.SelectedIndex = ddl.Items.IndexOf(item);
                            continue;
                        }

                        TextBox txt = c as TextBox;
                        if (txt != null)
                        {
                            txt.Text = searchCriteria[key].ToString();
                            continue;
                        }

                        Calendar cal = c as Calendar;
                        if (cal != null)
                        {
                            cal.Prompt = searchCriteria[key].ToString();
                            continue;
                        }

                        CheckBox cb = c as CheckBox;
                        if (cb != null)
                        {
                            cb.Checked = Convert.ToBoolean(searchCriteria[key]);
                            continue;
                        }

                        ListBox lb = c as ListBox;
                        if (lb != null)
                        {
                            string[] selectedValueList = searchCriteria[key].Split(',');
                            lb.SelectedIndex = defaultSelectedIndex;
                            if (selectedValueList != null)
                            {
                                foreach (string selectedValue in selectedValueList)
                                {
                                    lb.Items.FindByValue(selectedValue.Substring(1, selectedValue.Length - 2)).Selected = true;
                                }
                            }
                            continue;
                        }

                        /// Controls which are Label are subject to having their state set. However, not all labels are
                        /// deemed to contribute to the search criteria (for example, the labels which display selections made in one
                        /// or more of the pickers). Such lables are ignored (see comments in CommonSearch.CreateControls()).
                        Label lbl = c as Label;
                        if (lbl != null && lbl.Attributes["PickerSelection"] != null)
                        {
                            lbl.Visible = true;
                            continue;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Helper method to load a drop-down-list with a reference domain.
        /// </summary>
        /// <param name="list">Reference to the drop-down-list to load</param>
        /// <param name="string">Reference domain name to load</param>
        protected static void LoadDropDownList(DropDownList list, string refDomain)
        {
            ICachePolicy applicationCachePolicy = (ICachePolicy)HttpContext.Current.Application[Policy.Names.ApplicationCachePolicyKey];
            RefCodes refCodes = (RefCodes)applicationCachePolicy.GetCachedObject(RefCodes.CacheKey);
            if (refCodes == null)
            {
                throw new ApplicationException("Reference data not found in Application cache.");
            }

            list.Items.Add(CommonSearch.SelectPrompt);
            ArrayList domain = refCodes.GetRefCodes(refDomain);
            foreach (RefCode code in domain)
            {
                list.Items.Add(new ListItem(code.Meaning, code.Code));
            }
            list.Enabled = (list.Items.Count > 1);
        }

        /// <summary>
        /// Helper method to load a drop-down-list with data.
        /// </summary>
        /// <param name="list">Reference to the drop-down-list to load</param>
        /// <param name="table">DataTable which contains data to load</param>
        /// <param name="valueColumnName">Column Value</param>
        protected static void LoadDropDownList(DropDownList list, DataTable table, string valueColumnName)
        {
            LoadDropDownList(list, table, valueColumnName, 0);
        }

        /// <summary>
        /// Helper method to load a drop-down-list with data.
        /// </summary>
        /// <param name="list">Reference to the drop-down-list to load</param>
        /// <param name="table">DataTable which contains data to load</param>
        /// <param name="valueColumnName">Column Value</param>
        /// <param name="selectedIndex">Sets the Selected Index on the drop down.</param>
        protected static void LoadDropDownList(DropDownList list, DataTable table, string valueColumnName, int selectedIndex)
        {
            list.Items.Add(CommonSearch.SelectPrompt);
            foreach (DataRow row in table.Rows)
                list.Items.Add(new ListItem((string)row[0], row[valueColumnName].ToString()));
            list.SelectedIndex = selectedIndex;
            list.Enabled = (list.Items.Count > 1);
        }

        /// <summary>
        /// Reset all controls in a control collection to their default state.
        /// </summary>
        /// <param name="controls">Collections of controls</param>
        /// <remarks>
        /// This method iterates over the specified controls collections looking for limited type of controls. When it
        /// finds them, it sets the state of that control to its default condition (whatever that might be).
        /// Following types of controls are processed:
        /// 1. TextBox
        /// 2. DropDownList
        /// 3. CheckBox
        /// 4. ListBox(None selected by default)
        /// </remarks>
        public static void ResetControls(ControlCollection controls)
        {
            foreach (Control c in controls)
            {
                if (!(c is LiteralControl))
                {
                    DropDownList ddl = c as DropDownList;
                    if (ddl != null)
                    {
                        ddl.SelectedIndex = 0;
                        continue;
                    }

                    TextBox txt = c as TextBox;
                    if (txt != null)
                    {
                        txt.Text = string.Empty;
                        continue;
                    }

                    Calendar cal = c as Calendar;
                    if (cal != null)
                    {
                        cal.Reset();
                        continue;
                    }

                    CheckBox cb = c as CheckBox;
                    if (cb != null)
                    {
                        cb.Checked = false;
                        continue;
                    }

                    ListBox lb = c as ListBox;
                    if (lb != null)
                    {
                        lb.SelectedIndex = -1;
                        continue;
                    }

                    RadioButtonList rbl = c as RadioButtonList;
                    if (rbl != null)
                    {
                        rbl.SelectedIndex = 0;
                        continue;
                    }
                }
            }
        }


        /// <summary>
        /// Get all search criterial as a name-value collection.
        /// </summary>
        /// <remarks>
        /// This method iterates over the specified controls collections looking for limited type of controls. When it
        /// finds them, it add the name of the control and the current value (whatever that might be) to a collection.
        /// If any of the controls indicate that their current content is the special SelectPrompt, the selection will
        /// NOT be added to the collection.
        /// Following types of controls are processed:
        /// 1. TextBox
        /// 2. DropDownList
        /// 3. Label (see comments in CreateControls())
        /// 4. CheckBox
        /// 5. RadioButton
        /// </remarks>
        /// <param name="domainUserID">Domain User ID of the logged-in user</param>
        /// <param name="controls">Set of controls to look at</param>
        /// <returns>Collection of name/value pairs</returns>
        public static SearchCriteria GetSearchCriteria(int domainUserID, ControlCollection controls)
        {
            SearchCriteria searchCriteria = new SearchCriteria(domainUserID);
            try
            {
                foreach (Control c in controls)
                    if (!(c is LiteralControl) && ((WebControl)c).Attributes["ExcludeFromSearchCriteria"] == null)
                    {
                        DropDownList ddl = c as DropDownList;
                        if (ddl != null)
                        {
                            if (ddl.SelectedItem.Text != CommonSearch.SelectPrompt)
                            {
                                searchCriteria.Add(ddl.ID, ddl.SelectedItem.Value);
                                if (ddl.Attributes["Label"] != null)
                                    searchCriteria.ControlLabels.Add(ddl.ID,
                                        String.Format("{0}{1}{2}", ddl.Attributes["Label"], CommonSearch.LabelValueSeparator,
                                        ddl.SelectedItem.Text));

                            }
                            continue;
                        }

                        TextBox tb = c as TextBox;
                        if (tb != null)
                        {
                            string entry = tb.Text.Trim();
                            if ((entry.Length > 0) && (entry != CommonSearch.SelectPrompt))
                            {
                                searchCriteria.Add(tb.ID, entry);
                                if (tb.Attributes["Label"] != null)
                                    searchCriteria.ControlLabels.Add(tb.ID,
                                        String.Format("{0}{1}{2}", tb.Attributes["Label"], CommonSearch.LabelValueSeparator, entry));
                            }
                            continue;
                        }

                        Calendar calendar = c as Calendar;
                        if (calendar != null)
                        {
                            string date = calendar.Selection;
                            if (!String.IsNullOrEmpty(date) && date != CommonSearch.SelectPrompt)
                            {
                                searchCriteria[calendar.ID] = date;
                                if (calendar.Attributes["Label"] != null)
                                    searchCriteria.ControlLabels.Add(calendar.ID, String.Format("{0}{1}{2}",
                                        calendar.Attributes["Label"], CommonSearch.LabelValueSeparator, date));
                            }
                            continue;
                        }

                        CheckBox cb = c as CheckBox;
                        if (cb != null)
                        {
                            if (cb.Checked)
                            {
                                searchCriteria.Add(cb.ID, cb.Checked.ToString());
                                if (cb.Attributes["Label"] != null)
                                    searchCriteria.ControlLabels.Add(cb.ID,
                                        String.Format("{0}{1}{2}", cb.Attributes["Label"], CommonSearch.LabelValueSeparator, cb.Checked.ToString()));
                            }
                            continue;
                        }

                        ListBox lb = c as ListBox;
                        if (lb != null)
                        {
                            StringBuilder selectedItems = null;

                            if (lb.SelectedIndex != -1)
                            {
                                selectedItems = new StringBuilder(string.Empty);
                                foreach (ListItem li in lb.Items)
                                {
                                    if (li.Selected)
                                    {
                                        selectedItems = selectedItems.Length == 0 ? selectedItems.Append("'" + li.Value.ToString().Trim()) : selectedItems.Append("','" + li.Value.ToString().Trim());
                                    }
                                }
                                if (selectedItems.Length > 0)
                                {
                                    selectedItems.Append("'");
                                }
                                searchCriteria.Add(lb.ID, selectedItems.ToString());
                                if (lb.Attributes["Label"] != null)
                                    searchCriteria.ControlLabels.Add(lb.ID,
                                        String.Format("{0}{1}{2}", lb.Attributes["Label"], CommonSearch.LabelValueSeparator,
                                        selectedItems.ToString()));

                            }
                            continue;
                        }

                        Label l = c as Label;
                        if (l != null)
                        {
                            if (l.Text != CommonSearch.SelectPrompt)
                            {
                                searchCriteria.Add(l.ID, l.Text);
                            }
                            continue;
                        }

                        RadioButtonList rbl = c as RadioButtonList;
                        if (rbl != null)
                        {
                            searchCriteria.Add(rbl.ID, rbl.SelectedItem.Value);
                            if (rbl.Attributes["Label"] != null)
                                searchCriteria.ControlLabels.Add(rbl.ID,
                                    String.Format("{0}{1}{2}", rbl.Attributes["Label"], CommonSearch.LabelValueSeparator, rbl.SelectedItem.Text));
                            continue;
                        }

                    }
            }
            catch (Exception) { }

            return searchCriteria;
        }
    }
}
